#include "openmove_Prefix.h"
#include "SceneBase.h"
#include "OgreEngine.h"
#include "ExampleFrameListener.h"
#include "SkeletalAnimationFrameListener.h"
#include "OgreExternalTextureSourceManager.h"
#include "OgreExternalTextureSource.h"
#include "SceneGlamPetitLoup.h"
#include "SimpleFrameListener.h"

#include "OgreExternalTextureSourceManager.h"

static Vector3 s_LoupDirStart(2.94504, 44.615, -2.90231);

CSceneGlamPetitLoup :: CSceneGlamPetitLoup(COgreEngine &Creator, const String & Name, const int pos) : CSceneBase(Creator, Name, pos), m_pPluieTop(NULL), m_SnowRate(100)
{
	m_LoupDir = s_LoupDirStart;
}

CSceneGlamPetitLoup :: ~CSceneGlamPetitLoup(void)
{
}

void CSceneGlamPetitLoup :: Create(TCreatorEntities const &CreatorEntities, TCreatorNodes const &CreatorNodes, TCreatorLights const &CreatorLights, ENetConfig IsClient, Vector3 &CameraStartPos)
{
	CSceneBase::Create(CreatorEntities, CreatorNodes, CreatorLights, IsClient, CameraStartPos);

	Entity *ent = findEntity(String("glam-petitsloups-bones"));

	TCreatorEntities loupEnt;
	TCreatorNodes loupNode;
	if (NULL != ent && ent->hasSkeleton())
	{
		Bone *root = ent->getSkeleton()->getBone(0);
		Node::ChildNodeIterator it = root->getChildIterator();
		int next = 0;
		while (it.hasMoreElements())
		{
			Bone *child = static_cast<Bone *>(it.getNext());
			if (next < 0)
			{
				++next;
				//continue;
			}				
			Vector3 const &pos = child->getInitialPosition();
			Quaternion const &rot = child->getInitialOrientation();
			loupEnt.push_back(SEntity(child->getName(), "glam-petitsloups-loup.mesh", true));
			loupNode.push_back(SNode(child->getName(), child->getName(), pos, rot));
			next = 0;
		}

		AddGeometries(loupEnt, loupNode);
	}

	//m_Compositors.push_back("B&W");
	//m_Compositors.push_back("HDR");
}

void CSceneGlamPetitLoup :: Attach(void)
{
	CSceneBase::Attach();
	//m_pCurrentCamera->setPosition(-180.8f, 87.7f, 452.3f);
	//Quaternion Quat(Radian(Degree(0.0f)), Vector3(0, 1, 0));
	//m_pCurrentCamera->setOrientation(Quat);
	//m_pCurrentCamera->setDirection(0, 0, -1);
	//m_OgreEngine.m_pViewPort->setBackgroundColour(ColourValue(1.0f, 0.0f, 0.9f, 1.0f));
	
	//m_OgreEngine.m_pCurrentSceneManager->setSkyBox(true, "SkyBox/poursuite-foret");

	//m_OgreEngine.m_pCurrentSceneManager->setShadowTechnique(SHADOWTYPE_TEXTURE_MODULATIVE);
	//m_OgreEngine.m_pCurrentSceneManager->setShadowFarDistance(2000);
	//m_OgreEngine.m_pCurrentSceneManager->setShadowTextureSize(2048);
	//m_OgreEngine.m_pCurrentSceneManager->setShadowColour(ColourValue::Black);

	addParticleSystems();

	m_curScale = 1.0f;
	m_scaling = false;
	m_lastTime = m_Timer.getSeconds();
}

void CSceneGlamPetitLoup :: Detach(void)
{
	CSceneBase::Detach();
	removeParticleSystems();
}


bool CSceneGlamPetitLoup :: frameStarted(const FrameEvent& evt)
{
	CSceneBase::frameStarted(evt);

	if (0 && false == m_pCameraFrameListener->getMoveCamera())
	{
		Entity *clone = findEntity(String("glam-petitsloups"));
		if (NULL != clone && clone->hasSkeleton())
		{
			Bone *leftFoot = clone->getSkeleton()->getBone("ATE_LeftFoot");
			Bone *rightFoot = clone->getSkeleton()->getBone("ATE_RightFoot");
			if (NULL != leftFoot && NULL != rightFoot)
			{
				Vector3 pos = rightFoot->getWorldPosition() + (leftFoot->getWorldPosition() - rightFoot->getWorldPosition()) / 2.0f;
				pos.z += 50.0f;
				m_pCurrentCamera->setPosition( pos );
			}
		}
	}

	{
		Real curTime = m_Timer.getSeconds();
		Real elapsedTime = (curTime - m_lastTime) / 3.0f;
		if (m_scaling)
		{
			m_curScale += elapsedTime;
		}
		else
		{
			m_curScale -= elapsedTime;
		}
		m_curScale = std::min(3.0f, m_curScale);
		m_curScale = std::max(1.0f, m_curScale);
		Entity *clone = findEntity(String("glam-petitsloups"));
		if (NULL != clone)
		{
			//Real val = ((m_Timer.getSeconds() - 30.0f) / (m_resetParams.m_duration - 30.0f)) * 3.0f + 1.0f;
			//Real scale = std::max(1.0f, val);
			m_pSceneNode->getChild("glam-petitsloups")->setScale(m_curScale, m_curScale, m_curScale);
			m_OgreEngine.setDebugText("scale: " + StringConverter::toString(m_curScale));
			//m_OgreEngine.setDebugText("val: " + StringConverter::toString(val));
		}
	}
	if (m_pCameraFrameListener->mInputDevice->isKeyDown(KC_Z))
	{
		fakeAddEvent(SOpenMoveDisplayPacket::e_GPL_SetPetitLoup, 0.1);
	} 

	if (m_pCameraFrameListener->mInputDevice->isKeyDown(KC_X))
	{
		fakeAddEvent(SOpenMoveDisplayPacket::e_GE_AddParticle, 0.3);
	}

	if (m_pCameraFrameListener->mInputDevice->isKeyDown(KC_C) && m_pCameraFrameListener->mTimeUntilNextToggle <= 0)
	{
		fakeAddEvent(SOpenMoveDisplayPacket::e_GPL_StartScale, 0);
		m_pCameraFrameListener->mTimeUntilNextToggle = 1.0f;

	}
	if (m_pCameraFrameListener->mInputDevice->isKeyDown(KC_V) && m_pCameraFrameListener->mTimeUntilNextToggle <= 0)
	{
		fakeAddEvent(SOpenMoveDisplayPacket::e_GPL_StopScale, 0);
		m_pCameraFrameListener->mTimeUntilNextToggle = 1.0f;
	}

	updateParticleSystems();

	SceneNode *node = (SceneNode *)m_pSceneNode->getChild("glam-petitsloups");
	Entity *ent = findEntity(String("glam-petitsloups"));
	if (NULL != ent && NULL != node)
	{
		Vector3 distVec = ((node->getPosition() + ent->getSkeleton()->getBone(0)->getPosition()) - m_pCurrentCamera->getPosition());
		Real dist = distVec.length();
		dist += 150.0f;
		m_OgreEngine.m_pCurrentSceneManager->setShadowFarDistance(dist);
	}

	m_lastTime = m_Timer.getSeconds();

	return (true);
}

void CSceneGlamPetitLoup :: removeParticleSystems(void)
{
	//for (int i = 1; i <= 1; ++i)
	//{
	//	m_pSceneNode->removeAndDestroyChild("Snow" + StringConverter::toString(i));
	//	m_OgreEngine.m_pCurrentSceneManager->destroyParticleSystem("Snow" + StringConverter::toString(i));
	//}
	for (int i = 1; i <= 1; ++i)
	{
		m_pSceneNode->removeAndDestroyChild("Loups" + StringConverter::toString(i));
		m_OgreEngine.m_pCurrentSceneManager->destroyParticleSystem("Loups" + StringConverter::toString(i));
	}
}

void CSceneGlamPetitLoup :: addParticleSystems(void)
{
	ParticleSystem *system;

	//for (int i = 1; i <= 1; ++i)
	//{
	//	system = m_OgreEngine.m_pCurrentSceneManager->createParticleSystem("Snow" + StringConverter::toString(i), "PEExamples/snow");
	//	system->getEmitter(0)->setPosition(Vector3(0, 200, 0));
	//	m_pSceneNode->createChildSceneNode("Snow" + StringConverter::toString(i))->attachObject(system);
	//}

	for (int i = 1; i <= 1; ++i)
	{
		system = m_OgreEngine.m_pCurrentSceneManager->createParticleSystem("Loups" + StringConverter::toString(i), "openmove/glam");
		//system->getEmitter(0)->setPosition(Vector3(-4523.1, 886.9, 1086.4));
		system->getEmitter(0)->setPosition(Vector3(0, 0, 0));
		m_pSceneNode->createChildSceneNode("Loups" + StringConverter::toString(i))->attachObject(system);
	}
}

void CSceneGlamPetitLoup :: updateParticleSystems(void)
{
	for (int i = 1; i <= 1; ++i)
	{
		ParticleSystem *system = m_OgreEngine.m_pCurrentSceneManager->getParticleSystem("Loups" + StringConverter::toString(i));
		if (NULL != system)
		{
		ParticleEmitter *emitter = system->getEmitter(0);
		Vector3 pos = m_pCameraFrutsum[0]->getParentSceneNode()->getOrientation() * -Vector3::UNIT_Z;
		pos.normalise();
		//pos *= (StringConverter::parseReal(emitter->getParameter("width")) / 2.0f);
		pos += m_pCameraFrutsum[0]->getParentSceneNode()->getPosition();
		emitter->setPosition(pos);

		if (m_Timer.getSeconds() > 14.0f)
		{
			system->getAffector(0)->setParameter("force_vector", StringConverter::toString(m_LoupDir));		
			emitter->setEmissionRate(200);
		}
		else
		{
			emitter->setEmissionRate(0);
		}

		int last = (int)system->getNumParticles() - 1;
		if (last >= 0)
		{
			Particle *particle = system->getParticle(last);
			m_OgreEngine.setDebugText("particle pos: " + StringConverter::toString(particle->position));
		}
		}
	}
}

void CSceneGlamPetitLoup :: processEvents(void)
{
	CSceneBase::processEvents();

	ParticleSystem *system = m_OgreEngine.m_pCurrentSceneManager->getParticleSystem("Loups1");
	ParticleEmitter *emitter = system->getEmitter(0);
	emitter->setEmissionRate(0);

	for (TEvents::iterator It = m_Events.begin(); It != m_Events.end(); ++It)
	{
		switch (It->m_Packet.eventid)
		{
			case SOpenMoveDisplayPacket::e_GPL_SetSnow:
			{
				break;
			}
			case SOpenMoveDisplayPacket::e_GPL_SetPetitLoup:
			{
				Vector3 tmp = s_LoupDirStart;
#if 0
				tmp.x += (Math::RangeRandom(0, 1) - 0.5) * 300.0f;
				tmp.z += (Math::RangeRandom(0, 1) - 0.5) * 300.0f;
#else
				if (It->m_Packet.user_position_h > 0 && It->m_Packet.user_position_v > 0)
				{
					tmp.x += (It->m_Packet.user_position_h - 0.5) * 300.0f;
					tmp.z += (It->m_Packet.user_position_v - 0.5) * 300.0f;
				}
#endif
				m_LoupDir = tmp;

				break;
			}
			case SOpenMoveDisplayPacket::e_GPL_StartScale:
			{
				m_scaling = true;
				break;
			}
			case SOpenMoveDisplayPacket::e_GPL_StopScale:
			{
				m_scaling = false;
				break;
			}
			case SOpenMoveDisplayPacket::e_GE_AddParticle:
			{
				emitter->setEmissionRate(1);

				break;
			}
			default:
			{
				break;
			}
		}
	}
}
